package org.orzeszek.transfer;

import java.io.BufferedReader;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.InetAddress;
import java.net.URL;

/**
 * Default implementation of {@link Settings}.
 * 
 * @author Michael Gierasimiuk
 */
public class SettingsImpl implements Settings
{
  private static final int MIN_VALID_PORT = 0;

  private static final int MAX_VALID_PORT = 65535;

  private static final int DEFAULT_PORT = 30000;

  private int port;

  private InetAddress address;

  /**
   * Creates a new {@link SettingsImpl} instance.
   */
  public SettingsImpl()
  {
    this.port = DEFAULT_PORT;
  }

  @Override
  public void setPort( int port )
  {
    if ( isPortValid( port ) == false )
    {
      throw new IllegalArgumentException( "Cannot set port to " + port
          + ". Port must be an integer between 0 and 65535, inclusive." );
    }
    this.port = port;
  }

  @Override
  public int getPort()
  {
    return this.port;
  }

  @Override
  public void setAddress( InetAddress address )
  {
    this.address = address;
  }

  @Override
  public InetAddress getAddress()
  {
    if ( this.address == null )
    {
      try
      {
        URL url = new URL( "http://www.whatismyip.org/" );
        HttpURLConnection connection = (HttpURLConnection) url.openConnection();

        InputStream stream = connection.getInputStream();
        BufferedReader reader = new BufferedReader(
                                                    new InputStreamReader(
                                                                           stream ) );

        String ip = reader.readLine();
        return InetAddress.getByName( ip );
      }
      catch ( Exception e )
      {
        e.printStackTrace();
      }
    }
    return this.address;
  }

  /**
   * Returns true if the given port is in the valid port range. That is, if the
   * port is between 0 and 65535, the method will return true. Otherwise, the
   * method will return false. Ports 0 and 65535 are also valid.
   * 
   * @param port the port, to check if valid.
   * @return true if valid, false if not.
   */
  public static final boolean isPortValid( int port )
  {
    if ( port <= MAX_VALID_PORT && port >= MIN_VALID_PORT )
    {
      return true;
    }
    return false;
  }
}
